package org.wk.common.jpush;

import cn.jiguang.common.resp.APIConnectionException;
import cn.jiguang.common.resp.APIRequestException;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Options;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * @author df.wu
 */
@Component("clientPushService")
public class ClientPushService {

    private static Logger _log = LoggerFactory.getLogger(ClientPushService.class);

    private JPushClient jPushClient = new JPushClient(PushConstant.JPUSH_MASTER_SECRET, PushConstant.JPUSH_APP_KEY);

    public Boolean pushString(String pushStr){
        Boolean flag = Boolean.FALSE;
        try {
            PushResult result = jPushClient.sendPush(pushStr);
            if (null != result && result.isResultOK()) {
                flag = Boolean.TRUE;
            }
        } catch (APIConnectionException e) {
            _log.error(">>>>> Call pushAllPlatformByAlias APIConnectionException <<<<< ", e);
        } catch (APIRequestException e) {
            _log.error(">>>>> Call pushAllPlatformByAlias APIRequestException <<<<< ", e);
        }
        return flag;
    }

    public Boolean pushString(PushPayload payload){
        Boolean flag = Boolean.FALSE;
        try {
            PushResult result = jPushClient.sendPush(payload);
            if (null != result && result.isResultOK()) {
                flag = Boolean.TRUE;
            }
        } catch (APIConnectionException e) {
            _log.error(">>>>> Call pushAllPlatformByAlias APIConnectionException <<<<< ", e);
        } catch (APIRequestException e) {
            _log.error(">>>>> Call pushAllPlatformByAlias APIRequestException <<<<< ", e);
        }
        return flag;
    }
    /**
     * 通过别名发送通知
     * @param title 标题
     * @param content 内容
     * @param extras 扩展字段
     * @param alias 别名
     * @return
     */
    public Boolean pushAllPlatformByAlias(String title, String content, Map<String, String> extras,String... alias) {

        Notification notification = buildAllPlatformNotification(title, content, extras);

        PushPayload payload = PushPayload.newBuilder()
                .setPlatform(Platform.all())
                .setAudience(Audience.alias(alias))
                .setNotification(notification)
                .setOptions(Options.newBuilder().setApnsProduction(PushConstant.JPUSH_APNS_PRODUCTION).build())
                .build();
        Boolean flag = Boolean.FALSE;
        try {
            PushResult result = jPushClient.sendPush(payload);
            if (null != result && result.isResultOK()) {
                flag = Boolean.TRUE;
            }
        } catch (APIConnectionException e) {
            _log.error(">>>>> Call pushAllPlatformByAlias APIConnectionException <<<<< ", e);
        } catch (APIRequestException e) {
            _log.error(">>>>> Call pushAllPlatformByAlias APIRequestException <<<<< ", e);
        }
        return flag;
    }

    public Boolean pushAllPlatformByRegistrationId(String title, String content, Map<String, String> extras, String... registrationId) {

        Notification notification = buildAllPlatformNotification(title, content, extras);

        PushPayload payload = PushPayload.newBuilder()
                .setPlatform(Platform.all())
                .setAudience(Audience.registrationId(registrationId))
                .setNotification(notification)
                .setOptions(Options.newBuilder().setApnsProduction(PushConstant.JPUSH_APNS_PRODUCTION).build())
                .build();
        Boolean flag = Boolean.FALSE;
        try {
            PushResult result = jPushClient.sendPush(payload);
            if (null != result && result.isResultOK()) {
                flag = Boolean.TRUE;
            }
        } catch (APIConnectionException e) {
            _log.error(">>>>> Call pushAllPlatformByRegistrationId APIConnectionException <<<<< ", e);
        } catch (APIRequestException e) {
            _log.error(">>>>> Call pushAllPlatformByRegistrationId APIRequestException <<<<< ", e);
        }
        return flag;
    }

    /**
     * 推送全平台通知 通过tag
     * @param title 标题
     * @param content 内容
     * @param extras 扩展字段
     * @param tag tag
     * @return
     */
    public Boolean pushAllPlatformByTag(String title, String content, Map<String, String> extras, String... tag) {
        Notification notification = buildAllPlatformNotification(title, content, extras);

        PushPayload payload = PushPayload.newBuilder()
                .setPlatform(Platform.all())
                .setAudience(Audience.tag(tag))
                .setNotification(notification)
                .setOptions(Options.newBuilder().setApnsProduction(PushConstant.JPUSH_APNS_PRODUCTION).build())
                .build();
        Boolean flag = Boolean.FALSE;
        try {
            PushResult result = jPushClient.sendPush(payload);
            if (null != result && result.isResultOK()) {
                flag = Boolean.TRUE;
            }
        } catch (APIConnectionException e) {
            _log.error(">>>>> Call pushAllPlatformByTag APIConnectionException <<<<< ", e);
        } catch (APIRequestException e) {
            _log.error(">>>>> Call pushAllPlatformByTag APIRequestException <<<<< ", e);
        }
        return flag;
    }

    /**
     * 推送安卓平台 通过别名
     * @param title 标题
     * @param content 内容
     * @param extras 扩展字段
     * @param alias 别名
     * @return
     */
    public Boolean pushAndroidPlatformByAlias(String title, String content, Map<String, String> extras, String... alias) {
        Notification notification = buildAndroidNotification(title, content, extras);
        PushPayload payload = PushPayload.newBuilder()
                .setPlatform(Platform.android())
                .setAudience(Audience.alias(alias))
                .setNotification(notification)
                .setOptions(Options.newBuilder().setApnsProduction(PushConstant.JPUSH_APNS_PRODUCTION).build())
                .build();
        Boolean flag = Boolean.FALSE;
        try {
            PushResult result = jPushClient.sendPush(payload);
            if (null != result && result.isResultOK()) {
                flag = Boolean.TRUE;
            }
        } catch (APIConnectionException e) {
            _log.error(">>>>> Call pushAndroidPlatformByAlias APIConnectionException <<<<< ", e);
        } catch (APIRequestException e) {
            _log.error(">>>>> Call pushAndroidPlatformByAlias APIRequestException <<<<< ", e);
        }
        return flag;
    }

    /**
     * 推送IOS平台, 通过别名
     * @param title 标题
     * @param content 内容
     * @param extras 拓展字段
     * @param alias 别名
     * @return
     */
    public Boolean pushIosPlatformByAlias(String title, String content, Map<String, String> extras, String... alias) {
        Notification notification = buildIosNotification(title, content, extras);
        PushPayload payload = PushPayload.newBuilder()
                .setPlatform(Platform.ios())
                .setAudience(Audience.alias(alias))
                .setNotification(notification)
                .setOptions(Options.newBuilder().setApnsProduction(PushConstant.JPUSH_APNS_PRODUCTION).build())
                .build();
        Boolean flag = Boolean.FALSE;
        try {
            PushResult result = jPushClient.sendPush(payload);
            if (null != result && result.isResultOK()) {
                flag = Boolean.TRUE;
            }
        } catch (APIConnectionException e) {
            _log.error(">>>>> Call pushIosPlatformByAlias APIConnectionException <<<<< ", e);
        } catch (APIRequestException e) {
            _log.error(">>>>> Call pushIosPlatformByAlias APIRequestException <<<<< ", e);
        }
        return flag;
    }

    public Boolean pushAndroidPlatformByRegistrationId(String title, String content, Map<String, String> extras, String... registrationId) {
        Notification notification = buildAndroidNotification(title, content, extras);
        PushPayload payload = PushPayload.newBuilder()
                .setPlatform(Platform.android())
                .setAudience(Audience.registrationId(registrationId))
                .setNotification(notification)
                .setOptions(Options.newBuilder().setApnsProduction(PushConstant.JPUSH_APNS_PRODUCTION).build())
                .build();
        Boolean flag = Boolean.FALSE;
        try {
            PushResult result = jPushClient.sendPush(payload);
            if (null != result && result.isResultOK()) {
                flag = Boolean.TRUE;
            }
        } catch (APIConnectionException e) {
            _log.error(">>>>> Call pushAndroidPlatformByRegistrationId APIConnectionException <<<<< ", e);
        } catch (APIRequestException e) {
            _log.error(">>>>> Call pushAndroidPlatformByRegistrationId APIRequestException <<<<< ", e);
        }
        return flag;
    }

    public Boolean pushIosPlatformByRegistrationId(String title, String content, Map<String, String> extras, String... registrationId) {
        Notification notification = buildIosNotification(title, content, extras);
        PushPayload payload = PushPayload.newBuilder()
                .setPlatform(Platform.ios())
                .setAudience(Audience.registrationId(registrationId))
                .setNotification(notification)
                .setOptions(Options.newBuilder().setApnsProduction(PushConstant.JPUSH_APNS_PRODUCTION).build())
                .build();
        Boolean flag = Boolean.FALSE;
        try {
            PushResult result = jPushClient.sendPush(payload);
            if (null != result && result.isResultOK()) {
                flag = Boolean.TRUE;
            }
        } catch (APIConnectionException e) {
            _log.error(">>>>> Call pushIosPlatformByRegistrationId APIConnectionException <<<<< ", e);
        } catch (APIRequestException e) {
            _log.error(">>>>> Call pushIosPlatformByRegistrationId APIRequestException <<<<< ", e);
        }
        return flag;
    }

    public Boolean pushAndroidPlatformByTag(String title, String content, Map<String, String> extras, String... tag) {
        Notification notification = buildAndroidNotification(title, content, extras);
        PushPayload payload = PushPayload.newBuilder()
                .setPlatform(Platform.android())
                .setAudience(Audience.tag(tag))
                .setNotification(notification)
                .setOptions(Options.newBuilder().setApnsProduction(PushConstant.JPUSH_APNS_PRODUCTION).build())
                .build();
        Boolean flag = Boolean.FALSE;
        try {
            PushResult result = jPushClient.sendPush(payload);
            if (null != result && result.isResultOK()) {
                flag = Boolean.TRUE;
            }
        } catch (APIConnectionException e) {
            _log.error(">>>>> Call pushAndroidPlatformByTag APIConnectionException <<<<< ", e);
        } catch (APIRequestException e) {
            _log.error(">>>>> Call pushAndroidPlatformByTag APIRequestException <<<<< ", e);
        }
        return flag;
    }

    public Boolean pushIosPlatformByTag(String title, String content, Map<String, String> extras, String... tag) {
        Notification notification = buildIosNotification(title, content, extras);
        PushPayload payload = PushPayload.newBuilder()
                .setPlatform(Platform.ios())
                .setAudience(Audience.tag(tag))
                .setNotification(notification)
                .setOptions(Options.newBuilder().setApnsProduction(PushConstant.JPUSH_APNS_PRODUCTION).build())
                .build();
        Boolean flag = Boolean.FALSE;
        try {
            PushResult result = jPushClient.sendPush(payload);
            if ((null != result && result.isResultOK())) {
                flag = Boolean.TRUE;
            }
        } catch (APIConnectionException e) {
            _log.error(">>>>> Call pushIosPlatformByTag APIConnectionException <<<<< ", e);
        } catch (APIRequestException e) {
            _log.error(">>>>> Call pushIosPlatformByTag APIRequestException <<<<< ", e);
        }
        return flag;
    }

    /**
     * 构造Android/IOS  通知 标题+内容+扩展字段,不含message Notification
     * @param title
     * @param content
     * @param extras
     * @return
     */
    private Notification buildAllPlatformNotification(String title, String content, Map<String, String> extras) {
        Notification notification = Notification.newBuilder().addPlatformNotification(
                AndroidNotification.newBuilder()
                        .setTitle(title)
                        .setAlert(content)
                        .addExtras(extras)
                        .build()
        ).addPlatformNotification(IosNotification.newBuilder()
                .setBadge(1)
                .setSound("default")
                .setAlert(content)
                .addExtras(extras)
                .build()).build();
        return notification;
    }

    /**
     * 构造Android 通知 标题+内容+扩展字段, Notification
     * @param title
     * @param content
     * @param extras
     * @return
     */
    private Notification buildAndroidNotification(String title, String content, Map<String, String> extras) {
        Notification notification = Notification.newBuilder().addPlatformNotification(
                AndroidNotification.newBuilder()
                        .setTitle(title)
                        .setAlert(content)
                        .addExtras(extras)
                        .build()).build();
        return notification;
    }

    /**
     * 构造IOS 通知 内容+扩展字段
     * @param content
     * @param extras
     * @return
     */
    private Notification buildIosNotification(String content, Map<String, String> extras) {
        Notification notification = Notification.newBuilder().addPlatformNotification(
                IosNotification.newBuilder()
                        .setBadge(1)
                        .setSound("default")
                        .setAlert(content)
                        .addExtras(extras)
                        .build()).build();
        return notification;
    }
    /**
     * 构造IOS 通知 标题+内容+扩展字段,不含message Notification
     * @param title
     * @param content
     * @param extras
     * @return
     */
    private Notification buildIosNotification(String title, String content, Map<String, String> extras) {
        Notification notification = Notification.newBuilder().addPlatformNotification(
                IosNotification.newBuilder()
                        .setBadge(1)
                        .setSound("default")
                        .setAlert(content)
                        .addExtras(extras)
                        .build()).build();
        return notification;
    }
}
